<template>
    <iframe :style="style" frameborder="0" ref="iframe"></iframe>
</template>
<script>
/**
 * 编辑器容器
 * 用法: <editor-base v-model="formModel.content"></editor-base>
 */
export default {
    emits: ['update:modelValue'],
    props: {
        modelValue: {
            type: String,
            default: "",
        },
        style: {
            type: String,
            default: "width: 100%; height: 100%",
        },
    },
    watch: {
        modelValue(newVal) {
            this.$refs.iframe.contentDocument.body.innerHTML = this.htmldecode(newVal);
        },
        content(val) {
            this.$emit("update:modelValue", val);
        },
    },
    data() {
        return {
            content: this.modelValue,
        };
    },
    methods: {
        // 显示器全屏
        fullScreen(elContainer) {
            if (document.fullscreenElement) {
                document.exitFullscreen();
            } else {
                elContainer.requestFullscreen();
            }
        },
        // 浏览器窗口全屏
        fullWindow(elContainer) {
            if (elContainer.style.position == "fixed") {
                elContainer.dataset.fullWindow = "0";
                elContainer.style.position = "static";
                elContainer.style.zIndex = 1;
            } else {
                elContainer.dataset.fullWindow = "1";
                elContainer.style.position = "fixed";
                elContainer.style.top = 0;
                elContainer.style.bottom = 0;
                elContainer.style.left = 0;
                elContainer.style.right = 0;
                elContainer.style.zIndex = 999;
            }
        },
        // 执行命令
        execCommand(cmd) {
            let elIframe = this.$refs.iframe;
            switch (cmd) {
                case "bold":
                    // 加粗
                    elIframe.contentDocument.execCommand("bold");
                    break;
                case "underline":
                    // 下划线
                    elIframe.contentDocument.execCommand("underline");
                    break;
                case "sc":
                    // 删除线
                    elIframe.contentDocument.execCommand("underline");
                    break;
                case "italic":
                    // 斜体
                    elIframe.contentDocument.execCommand("italic");
                    break;
                case "copy":
                    // 复制
                    elIframe.contentDocument.execCommand("copy");
                    break;
                case "cut":
                    // 剪切
                    elIframe.contentDocument.execCommand("cut");
                    break;
                case "select":
                    // 全选
                    elIframe.contentDocument.execCommand("selectAll");
                    break;
                case "paste":
                    // 粘贴
                    alert(
                        "该功能尚未支持! 请使用浏览器右键 [粘贴] 或者键盘快捷键 [ctrl+v]"
                    );
                    break;
                case "delete":
                    // 删除选中的内容
                    elIframe.contentDocument.execCommand("Delete");
                    break;
                case "fonts":
                    // 设置字体
                    //改变选中区域的字体;
                    // elIframe.execCommand("FontName", false, sFontName);
                    //改变选中区域的字体大小;
                    // elIframe.execCommand("FontSize", false, sSize | iSize);
                    //设置前景颜色;
                    // elIframe.execCommand("ForeColor", false, sColor);
                    break;
                case "html":
                    // HTML代码
                    if (elIframe.contentDocument.body.dataset.isEspace == "0") {
                        elIframe.contentDocument.body.innerHTML = this.htmldecode(
                            elIframe.contentDocument.body.innerHTML
                        );
                        elIframe.contentDocument.body.dataset.isEspace = "1";
                    } else {
                        elIframe.contentDocument.body.innerHTML = this.htmlencode(
                            elIframe.contentDocument.body.innerHTML
                        );
                        elIframe.contentDocument.body.dataset.isEspace = "0";
                    }
                    break;
                case "preview":
                    // 预览（弹窗）
                    let win = window.open("", "_blank");
                    win.focus();
                    win.document.title = " 预览";
                    win.document.body.innerHTML = elIframe.contentDocument.body.innerHTML;
                    break;
                case "print":
                    // 打印
                    elIframe.contentDocument.execCommand("print");
                    break;
                default:
                    break;
            }
        },
        // 在当前光标位置插入内容
        insertHtml(html) {
            let selection = this.$refs.iframe.contentWindow.getSelection();
            if (selection.rangeCount > 0) {
                let range = selection.getRangeAt(0);
                range.collapse(false);
                let documentFragment = range.createContextualFragment(html);
                range.insertNode(documentFragment);
            } else {
                this.$refs.iframe.contentDocument.body.innerHTML += html;
            }
        },
        htmlencode(html) {
            return html
                .replace(/&/g, "&amp;")
                .replace(/</g, "&lt;")
                .replace(/>/g, "&gt;")
                .replace(/"/g, "&quot;");
        },
        htmldecode(text) {
            return text
                .replace(/&lt;/g, "<")
                .replace(/&gt;/g, ">")
                .replace(/&quot;/g, '"')
                .replace(/&amp;/g, "&");
        },
    },
    mounted() {
        this.$refs.iframe.contentDocument.designMode = "on";
        // 监听文档内容的变化
        new MutationObserver((mutationsList, observer) => {
            // console.log("[H5VisiualEditor] mutationsList=", mutationsList);
            // console.log("[H5VisiualEditor] observer=", observer);
            this.content = this.htmlencode(
                this.$refs.iframe.contentDocument.body.innerHTML
            );
        }).observe(this.$refs.iframe.contentDocument.body, {
            attributes: true, // 修改目标节点属性时会收到通知
            childList: true, // childList：添加、删除目标节点的子节点时会收到通知（子节点的后代节点添加或删除时不会收到通知）
            subtree: true, // 目标节点或后代节点变更时都会触发，必须配合其他属性一起使用
            attributeOldValue: true, // 表示需要记录改变前的目标属性值，设置了attributeOldValue可以省略attributes设置
            characterData: true, // 观察目标节点下所有文本类型节点（即子代或后代）的文字变化（注意：添加、删除文本节点不会被观察到，如果改变之前的类型不是文本节点也不会被观察到），该属性只能配合subtree使用。
        });
    }
}
</script>